<?php
// +----------------------------------------------------------------------
// | 海豚PHP框架 [ DolphinPHP ]
// +----------------------------------------------------------------------
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
// +----------------------------------------------------------------------
// | 官方网站: http://dolphinphp.com
// +----------------------------------------------------------------------

namespace app\mill\model;

use think\Model;
use app\admin\model\Config as ConfigModel;
use think\Db;
use app\mill\model\Give as GiveModel;
use app\mill\model\Plan as PlanModel;

/**
 * 面积表模型
 */
class Archives extends Model
{
    // 设置当前模型对应的完整数据表名称
    protected $name = 'mill_order_archives';

    // 自动写入时间戳
    protected $autoWriteTimestamp = true;

    // 定义表格字段
    public static $fields = [
        'sort'          =>  '序号',
        'page'          =>  '图号',
        'model_sn'      =>  '编号',
        'number'        =>  '数量',
        'thickness'     =>  '板厚(MM)',
        'high'          =>  '宽(H)',
        'long'          =>  '长(L)',
        'one_area'      =>  '单件面积(M²)',
        'row_area'      =>  '合计面积(M²)',
        'color'         =>  '颜色',
        //'cutting'       =>  '开平',
        //'size'          =>  '尺寸',
        'model'         =>  '板型',
        //'plank'         =>  '材料名称',
    ];

    // 面积表附加字段
    public static $add_fields = [
        'torque'        =>  '超宽',
        'bend'          =>  '超长',
        'knife'         =>  '刀数',
        'make'          =>  '组装',
        'mspell'        =>  '密拼',
        'process'       =>  '复合',
        'small'         =>  '超小',
        'carve'         =>  '雕刻',
        'punch'         =>  '冲孔',
        'net'           =>  '拉网',
        'arc'           =>  '圆弧',
        'part'          =>  '小件',
    ];

    // 定义已发货表格字段
    public static $fields4 = [
        'sort'          =>  '序号',
        'model_sn'      =>  '编号',
        'number'        =>  '数量',
        'thickness'     =>  '板厚(MM)',
        'one_area'      =>  '单件面积(M²)',
        'row_area'      =>  '合计面积(M²)',
        'weld'          =>  '单件焊缝(米)',
        'weld_sum'      =>  '合计焊缝(米)',
        'slot'          =>  '单件开槽(米)',
        'slot_sum'      =>  '合计开槽(米)',
        'color'         =>  '颜色',
        'model'         =>  '板型',
        'knife'         =>  '工艺',
        'note'          =>  '备注',
        //'konghang'      =>  '',
        'archives_id'   =>  '',
    ];

    /**
     * 获取面积表信息
     * @param null $id order_id
     * @param string $fields field
     * @param string $order order
     * @param string $group group
     * @param array $join join
     * @param array $where where
     * @param string $table table
     * @return array|\PDOStatement|string|\think\Collection
     */
    public static function getList($id = null,$fields = '',$order = "CONVERT (REPLACE(a.sort,'#','999999'),signed) ASC",$group = '',$join = [],$where = [],$table = 'mill_order_archives'){
        if (!$id && empty($where))return [];
        if(empty($order))$order = "CONVERT (REPLACE(a.sort,'#','999999'),signed) ASC";

        if(empty($where))$where[] = ['a.order_id','=',$id];
        $fields = $fields?$fields:array_keys(self::$fields);

        $lists = Db::name($table)->alias('a')->field($fields)->join($join)->where($where)->group($group)->orderRaw($order)->select();

        return $lists;

    }

    // 统计工程面积表信息
    public static function getOneStat($val = null,$field = 'order_id',$condition = 'eq',$map = [],$time = [],$status = 0){
        $where[] = [$field,$condition,$val];
        $where_give = [['quality_status','>=',0]];
        $where_give_is_p = [['is_process','=',0]];
        if(!empty($map))$where = $map;
        if(empty($time[0]))$time[0] = 0;
        if(empty($time[1]))$time[1] = time();
        $data['number_sum'] = Db::name('mill_order_archives')->where($where)->sum('number');
        if(!empty($status)){
            $data["status_sum"] = Db::name('mill_order_archives_give')->where($where)->where($where_give)->where("status{$status}_time > {$time[0]} and status{$status}_time <= {$time[1]}")->count();
            $data["status_no"] = $data['number_sum']-$data["status_sum"];
        }
        else{
            $data['status1'] = Db::name('mill_order_archives_give')->where($where)->where($where_give)->where("status1_time > {$time[0]} and status1_time <= {$time[1]}")->count();
            $data['status1_no'] = $data['number_sum']-$data['status1'];
            $data['status2'] = Db::name('mill_order_archives_give')->where($where)->where($where_give)->where("status2_time > {$time[0]} and status2_time <= {$time[1]}")->count();
            $data['status2_no'] = $data['number_sum']-$data['status2'];
            $data['status3'] = Db::name('mill_order_archives_give')->where($where)->where($where_give)->where("status3_time > {$time[0]} and status3_time <= {$time[1]}")->count();
            $data['status3_no'] = $data['number_sum']-$data['status3'];
            $data['status4'] = Db::name('mill_order_archives_give')->where($where)->where($where_give)->where("status4_time > {$time[0]} and status4_time <= {$time[1]}")->count();
            $data['status4_no'] = $data['number_sum']-$data['status4'];
            $data['status5'] = Db::name('mill_order_archives_give')->where($where)->where($where_give)->where("status5_time > {$time[0]} and status5_time <= {$time[1]}")->count();
            $data['status5_no'] = $data['number_sum']-$data['status5'];
            $data['status6'] = Db::name('mill_order_archives_give')->where($where)->where($where_give)->where("status6_time > {$time[0]} and status6_time <= {$time[1]}")->count();
            $data['status6_no'] = $data['number_sum']-$data['status6'];
            $data['status7'] = Db::name('mill_order_archives_give')->where($where)->where($where_give)->where($where_give_is_p)->where("status7_time > {$time[0]} and status7_time <= {$time[1]}")->count();
            $data['status7_no'] = $data['number_sum']-$data['status7'];
            $data['status8'] = Db::name('mill_order_archives_give')->where($where)->where($where_give)->where($where_give_is_p)->where("status8_time > {$time[0]} and status8_time <= {$time[1]}")->count();
            $data['status8_no'] = $data['number_sum']-$data['status8'];
        }

        $status_s = !empty($status)?$status:GiveModel::$role[8]['status'][0];
        $where2[] = ['g.'.$field,$condition,$val];
        $where2[] = ['g.quality_status','>=',0];
        $where_give_is_p = [['g.is_process','=',0]];
        $data['area_sum'] = Db::name('mill_order_archives')->where($where)->sum('one_area*number');
        $data['area_sum'] = round($data['area_sum'],4);
        $data['area_ok_sum'] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where("g.status>={$status_s}")->sum('a.one_area');
        $data['area_ok_sum'] = round($data['area_ok_sum'],4);
        $data['area_on_sum'] = $data['area_sum']-$data['area_ok_sum'];

        $data['number_ok_sum'] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where("g.status>={$status_s}")->count();
        $data['number_ok_sum'] = intval($data['number_ok_sum']);
        $data['number_on_sum'] = $data['number_sum']-$data['number_ok_sum'];

        if(!empty($status)){
            $data["status_area_sum"] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where("g.status{$status}_time > {$time[0]} and g.status{$status}_time <= {$time[1]}")->sum('a.one_area');
            $data["status_area_sum"] = round($data["status_area_sum"],6);
            $data["status_area_on_sum"] = $data['area_sum']-$data["status_area_sum"];
        }
        else{
            //已开料面积
            $data['status1_area_sum'] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where("g.status1_time > {$time[0]} and g.status1_time <= {$time[1]}")->sum('a.one_area');
            $data['status1_area_sum'] = round($data['status1_area_sum'],4);
            //未开料面积
            $data['status1_area_on_sum'] = $data['area_sum']-$data['status1_area_sum'];
            //已折弯面积
            $data['status2_area_sum'] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where("g.status2_time > {$time[0]} and g.status2_time <= {$time[1]}")->sum('a.one_area');
            $data['status2_area_sum'] = round($data['status2_area_sum'],4);
            //未折弯面积
            $data['status2_area_on_sum'] = $data['area_sum']-$data['status2_area_sum'];
            //已焊接面积
            $data['status3_area_sum'] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where("g.status3_time > {$time[0]} and g.status3_time <= {$time[1]}")->sum('a.one_area');
            $data['status3_area_sum'] = round($data['status3_area_sum'],4);
            //未焊接面积
            $data['status3_area_on_sum'] = $data['area_sum']-$data['status3_area_sum'];
            //已组装面积
            $data['status4_area_sum'] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where("g.status4_time > {$time[0]} and g.status4_time <= {$time[1]}")->sum('a.one_area');
            $data['status4_area_sum'] = round($data['status4_area_sum'],4);
            //未组装面积
            $data['status4_area_on_sum'] = $data['area_sum']-$data['status4_area_sum'];
            //已打磨面积
            $data['status5_area_sum'] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where("g.status5_time > {$time[0]} and g.status5_time <= {$time[1]}")->sum('a.one_area');
            $data['status5_area_sum'] = round($data['status5_area_sum'],4);
            //未打磨面积
            $data['status5_area_on_sum'] = $data['area_sum']-$data['status5_area_sum'];
            //已喷涂面积
            $data['status6_area_sum'] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where("g.status6_time > {$time[0]} and g.status6_time <= {$time[1]}")->sum('a.one_area');
            $data['status6_area_sum'] = round($data['status6_area_sum'],4);
            //未喷涂面积
            $data['status6_area_on_sum'] = $data['area_sum']-$data['status6_area_sum'];
            //已复合面积
            $data['status7_area_sum'] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where($where_give_is_p)->where("g.status7_time > {$time[0]} and g.status7_time <= {$time[1]}")->sum('a.one_area');
            $data['status7_area_sum'] = round($data['status7_area_sum'],4);
            //未复合面积
            $data['status7_area_on_sum'] = $data['area_sum']-$data['status7_area_sum'];
            //已发货面积
            $data['status8_area_sum'] = Db::name('mill_order_archives_give')->alias('g')->leftJoin('mill_order_archives a','a.id=g.archives_id')->where($where2)->where($where_give_is_p)->where("g.status8_time > {$time[0]} and g.status8_time <= {$time[1]}")->sum('a.one_area');
            $data['status8_area_sum'] = round($data['status8_area_sum'],4);
            //未发货面积
            $data['status8_area_on_sum'] = $data['area_sum']-$data['status8_area_sum'];
        }

        return $data;
    }

    // 插入产品明细
    public static function checkGive($id=null,$archives_id=null){
        $config = new ConfigModel();

        $where = $where2 = ['order_id'=>$id];
        if(!empty($archives_id)){
            $where = ['archives_id'=>$archives_id];
            $where2 = ['id'=>$archives_id];
        }
        $count = Db::name('mill_order_archives_give')->where($where)->count();

        if(empty($count)){

            if(empty($archives_id)){
                //当天生产批次配置
                $mill_date_batch = $config->getConfig('mill_date_batch');
                //如果不是当天生产批次，则重置
                if($mill_date_batch['date']!=date('Ymd')){
                    $mill_date_batch['date'] = date('Ymd');
                    $mill_date_batch['batch'] = 0;
                }
                $mill_date_batch['batch'] += 1;
                $mill_date_batch['sort'] = 1;
            }
            else{
                $last_give = Db::name('mill_order_archives_give')->where(['order_id'=>$id])->order('sort desc')->find();
                $mill_date_batch['date'] = $last_give['give_date'];
                $mill_date_batch['batch'] = $last_give['batch'];
                $mill_date_batch['sort'] = $last_give['sort']+1;
            }

            //当天日期
            $date = $mill_date_batch['date'];
            //当前批次
            $batch = $mill_date_batch['batch'];
            //当前序号，从1开始
            $sort = $mill_date_batch['sort'];

            $order = Db::name('mill_order')->where('id='.$id)->find();
            $list = self::getList(null,'id,order_id,order_pid,sort,number,sort','','',[],$where2,'mill_order_archives');
            $add_arr = [];
            foreach ($list as $v){

                if($v['number'] >= 1){
                    for ($i=1;$i<=$v['number'];$i++){
                        $add = [
                            'order_id'      =>  $v['order_id'],
                            'order_pid'     =>  $v['order_pid'],
                            'archives_id'   =>  $v['id'],
                            'archives_sn'   =>  $order['archives_sn'],
                            'number'        =>  1,
                            'counter'       =>  $i,
                            'give_date'     =>  $date,
                            'batch'         =>  $batch,
                            'sort'          =>  $sort,
                            'give_sn'       =>  GiveModel::giveSn($date,$batch,$sort,$v['order_id']),
                        ];
                        $add_arr[] = $add;

                        $sort++;
                    }
                }
            }

            //2000条数据为一批次
            $add_arr_i = intval($sort/2000)+1;
            $add_arr_arr = array_chunk($add_arr, $add_arr_i);
            //分批次插入
            foreach ($add_arr_arr as $varr){
                Db::name('mill_order_archives_give')->insertAll($varr);
            }

            //更新当天生产批次配置
            if(empty($archives_id))ConfigModel::where('name', 'mill_date_batch')->update(['value' => "date:{$date}\r\nbatch:{$batch}"]);
        }

        return true;
    }

    // 检查更新产品状态
    public static function checkStatus($id=null,$status=0){
        if($status>0){
            $where = ['a.id'=>$id];
            $data = Db::name('mill_order_archives')
                ->alias('a')
                ->field('o.*,a.order_id,a.number')
                ->leftJoin('mill_order o','o.id=a.order_id')
                ->where($where)
                ->find();
            $count = Db::name('mill_order_archives_give')->where(['archives_id'=>$id])->where('status>='.$status)->count('id');

            $end_time = 0;
            if($count >= $data['number']){

                $update = ['a.status'=>$status+1];
                Db::name('mill_order_archives')->alias('a')->where($where)->update($update);

                $give_sort = explode(',',$data['give_sort']);
                array_pop($give_sort);//删除最后一个生产状态，即发货状态
                $status_end = array_pop($give_sort);//除开发货后，最后一个生产状态

                //更新工程生产周期
                if($status == $status_end){
                    $give_pro_min = Db::name('mill_order_archives_give')->where(['order_id'=>$data['order_id']])->order('status1_time asc')->value('status1_time');
                    $give_pro_max = Db::name('mill_order_archives_give')->where(['order_id'=>$data['order_id']])->order("status{$status_end}_time desc")->value("status{$status_end}_time");
                    $give_pro = ceil(($give_pro_max/86400)-($give_pro_min/86400));
                    Db::name('mill_order')->where(['id'=>$data['order_id']])->update(['give_pro'=>$give_pro]);
                }

                $status_count = Db::name('mill_order_archives_give')->where(['order_id'=>$data['order_id']])->where('status < '.$status)->count('id');
                if(empty($status_count))$end_time = time();

            }

            //更新排产计划单
            PlanModel::updatePlan($data,$status,0,time(),$end_time);

            //更新工程产品状态
            $give_status = Db::name('mill_order_archives_give')->where(['order_id'=>$data['order_id']])->order('status desc')->value('status');

            Db::name('mill_order')->where(['id'=>$data['order_id']])->update(['give_status'=>$give_status]);
        }
    }

    /**
     * 获取面积表文档的开料信息并编译
     * @param null $id 附件ID
     * @return array|\PDOStatement|string|\think\Collection
     */
    public static function archivesCutting($id = null)
    {

        // 接收附件 ID
        if(empty($id))return false;
        // 获取附件 ID 完整路径
        $file = get_file_path($id);
        //$full_path = 'D:/office/phpstudy_pro/WWW/xxy/public/uploads/files/20210611/49dc8272891a2dbdc3396fc055d8017c.xls';
        if(strpos(getcwd(),'public') && strpos($file,'public'))$file = explode('public',$file)[1];
        $full_path = getcwd() . $file;

        $head_table = [
            'sheet'         =>  '开料表',
            'rowStart'      =>  2,
            'rowEnd'        =>  2,
            'table'         =>  'order',
            'fields'        =>  [
                'C-2'       =>  'engineering',
                'F-2'       =>  'order_sn',
                'I-2'       =>  'batch',
                'N-2'       =>  'cutting_batch',
            ]
        ];

        $archives_table = [
            'sheet'         =>  '开料表',
            'rowStart'      =>  6,
            //'rowEnd'        =>  5,
            'table'         =>  'order_archives_cutting',
            'fields'        =>  [
                'A'         =>  'sort',
                'B'         =>  'page',
                'C'         =>  'model_sn',
                'D'         =>  'thickness',
                'E'         =>  'high2',
                'F'         =>  'long2',
                'G'         =>  'number2',
                'H'         =>  'high',
                'I'         =>  'long',
                'J'         =>  'number',
                'K'         =>  'cutting_sn',
                'L'         =>  'note',
                'M'         =>  'cutting_sort',
                'O'         =>  'is_cutting',
            ],
        ];
        $sheet_read_arr = [$head_table,$archives_table];

        try {
            $import = plugin_action('Excel/Excel/importarchives', [$full_path,$sheet_read_arr]);
        } catch (\Exception $e) {
            return false;
        }

        return $import;

    }
    // 检查更新开料面积表
    public static function updateArchivesCutting($order = []){

        //设置更新时间，用于删除开料面积表里不要的数据
        $time = time();
        //材质，暂时默认
        $plank = '';

        //批量新增，减少服务器负担
        $add_arr = [];
        //获取开料面积表
        $list = self::archivesCutting($order['waiback_drawing']);

        if(empty($list['order_archives_cutting']['lists']))return '面积表格式不正确，请检查后重新上传';
        //获取开料批次信息
        $order_cutting = $list['order']['lists'][0];
        //验证开料批次是否唯一
        $isBatch = Db::name('mill_order_archives_cutting_drawing')->where(['order_id'=>$order['id'],'cutting_batch'=>$order_cutting['cutting_batch']])->value('id');

        //修改
        if(empty($order['is_add'])){
            if(!empty($isBatch) && $isBatch != $order['drawing_id'])return '开料批次不一致';
        }
        //新增
        else{
            if(!empty($isBatch))return '该开料批次已存在';
        }

        //更新开料批次信息
        if(!empty($order['drawing_id'])){
            Db::name('mill_order_archives_cutting_drawing')->where(['id'=>$order['drawing_id']])->update(['cutting_batch'=>$order_cutting['cutting_batch']]);
        }

        if(!empty($list['order_archives_cutting']['lists'])){
            foreach ($list['order_archives_cutting']['lists'] as $v){

                //如果套料为空，则不记录到数据库
                //if(empty($v['cutting_sn']))continue;
                //如果为空，则不记录到数据库
                if(empty($v['is_cutting']))continue;
                $add = $v;

                //如果开平序号不为空，则为主体
                if(!empty($add['cutting_sort']))$add['is_main'] = 1;
                else $add['is_main'] = 0;

                $add['order_id'] = $order['id'];//工程ID
                $add['order_pid'] = $order['order_pid'];//工程PID
                $add['archives_sn'] = $order['archives_sn'];//工程档案号
                $add['plank'] = $plank;//材质
                $add['update_time'] = $time;//更新时间
                $add['thickness'] = empty($add['thickness'])?2.5:$add['thickness'];//默认板厚2.5

                if(!empty($order['drawing_id']))$add['drawing_id'] = $order['drawing_id'];//开料表图纸ID

                //用料规格
                if($add['is_main']){
                    $add['long_hs'] = sprintf("%.2f", (ceil($add['long']*$add['number']/10)/100));//长（换算后）  向上保留两位小数
                    $add['one_area'] = sprintf("%.6f", (ceil($add['long']*$add['high'])/1000000));//单件面积=长*宽  向上保留六位小数
                    $add['row_area'] = sprintf("%.6f", round($add['one_area']*$add['number'],6));//合计面积  四舍五入保留六位小数
                    $add['num'] = sprintf("%.2f", (ceil($add['one_area']*$add['thickness']*272)/100));//单件重量=面积*板厚*2.72  向上保留两位小数
                    $add['row_num'] = sprintf("%.2f", (round($add['num']*$add['number'],2)));//合计重量  四舍五入保留两位小数
                }
                else{
                    $add['long_hs'] = '';
                    $add['one_area'] = '';
                    $add['row_area'] = '';
                    $add['num'] = '';
                    $add['row_num'] = '';
                }

                //获取开料ID
                $where = [
                    'order_id'      =>  $order['id'],//工程ID
                    'cutting_sn'    =>  $add['cutting_sn'],//套料
                    'cutting_sort'  =>  $add['cutting_sort'],//开平序号
                    'sort'          =>  $add['sort'],//面积表序号
                ];
                $cutting_id = Db::name('mill_order_archives_cutting')->where($where)->value('id');


                //包含中文的，默认开平已完成
                if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $add['cutting_sn'], $match)) {

                    $cutting = Db::name('mill_order_archives_cutting')->where(['id'=>$cutting_id])->find();

                    $log = Db::name('mill_order_archives_cutting_log')->where(['cutting_id'=>$cutting_id])->find();
                    if(empty($log)){

                        $log_add = $cutting;
                        unset($log_add['id']);

                        $log_add['uid'] = UID;
                        $log_add['status'] = 1;
                        $log_add['cutting_id'] = $cutting['id'];
                        $log_add['cutting_log_sn'] = "现成的{$order['archives_sn']}-{$order_cutting['cutting_batch']}";
                        $log_add['cutting_log_time'] = time();
                        //$log_add['cutting_number'] = $cutting['number'];

                        //新增开平记录
                        Db::name('mill_order_archives_cutting_log')->insert($log_add);

                        Db::name('mill_order_archives_cutting')->where(['id'=>$cutting_id])->update(['status'=>1]);
                    }
                    Db::name('mill_order_archives_cutting_log')->where(['cutting_id'=>$cutting_id])->update(['cutting_number'=>$cutting['number']]);

                }

                //新增
                if(empty($cutting_id))$add_arr[] = $add;
                //更新
                else {
                    Db::name('mill_order_archives_cutting')->where(['id'=>$cutting_id])->update($add);
                    Db::name('mill_order_archives_cutting_log')->where(['cutting_id'=>$cutting_id])->update($add);
                }

            }

            //批量新增
            if(!empty($add_arr))Db::name('mill_order_archives_cutting')->insertAll($add_arr);
            //时间未更新的，默认为要删除的数据
            Db::name('mill_order_archives_cutting')->where([['order_id','=',$order['id']],['drawing_id','=',$order['drawing_id']],['update_time','<>',$time]])->delete();

        }

    }

}
